home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / MOS / XBRA.I < prev   
Encoding:
Modula Implementation  |  1991-02-10  |  6.8 KB  |  255 lines

  1.  
  2. IMPLEMENTATION MODULE XBRA;
  3.  
  4. (*
  5.   18.06.89 Thomas Tempelmann: Megamax-Version
  6.   24.10.90 Thomas Tempelmann: $H+
  7.   04.11.90 Thomas Tempelmann: $S-
  8.   10.02.91 Thomas Tempelmann: Neben dem Null-Ptr wird nun auch ein Ptr auf sich
  9.                               selbst als Listenende gewertet, da das proTOS für
  10.                               den hyperCACHE 030 solche XBRA-Listen anlegt.
  11. *)
  12.  
  13. (*$Y+,H+,R-,S-*)
  14.  
  15. FROM SYSTEM IMPORT ASSEMBLER;
  16.  
  17. FROM SYSTEM IMPORT ADR, ADDRESS, BYTE;
  18.  
  19. FROM SysUtil1 IMPORT SuperPeek, SuperLPeek, SuperLPoke;
  20.  
  21. (*
  22. IMPORT XBIOS;
  23. *)
  24.  
  25. CONST
  26.   JmpInstr = 4EF9H; (* Code für 'JMP <adr>.L' *)
  27.  
  28. (* für nicht-Megamax-Systeme:
  29.   MODULE SysUtil1;
  30.   
  31.    (*
  32.     * lokales Modul mit Funktionen zum Zugriff auf Daten im Supervisor-Modus
  33.     * ----------------------------------------------------------------------
  34.     *
  35.     * Die in diesem Modul verwendeten Funktionen
  36.     *   SuperPeek, SuperLPeek und SuperLPoke
  37.     * dienen dazu, Daten im Supervisor-Mode zuzuweisen. Sie sind folgender-
  38.     * maßen definiert:
  39.     *   PROCEDURE SuperPeek  ( addr: ADDRESS; VAR data: ARRAY OF BYTE );
  40.     *     liest ab der Adresse 'addr' die Anzahl von 'HIGH (data)+1' Bytes.
  41.     *   PROCEDURE SuperLPeek ( addr: ADDRESS ): LONGCARD;
  42.     *     liefert 4 Bytes ab Adresse 'addr'.
  43.     *   PROCEDURE SuperLPoke ( addr: ADDRESS; data: LONGCARD );
  44.     *     weist 4 Bytes ab Adresse 'addr' zu.
  45.     * Diese Funktionen müssen auch korrekt ablaufen, wenn bereits bei ihrem
  46.     * Aufruf der Supervisor-Mode aktiv ist. Sie können wahlweise durch Verwen-
  47.     * dung der Funktion 'XBIOS.SuperExec' ('sup_exec()') oder mit 'GEMDOS.Super'
  48.     * ('super()') implementiert werden.
  49.     *)
  50.   
  51.     IMPORT ADR, ADDRESS, BYTE;
  52.     FROM XBIOS IMPORT SuperExec;
  53.   
  54.     EXPORT SuperPeek, SuperLPeek, SuperLPoke;
  55.   
  56.     VAR from, to: POINTER TO BYTE; bytes: CARDINAL;
  57.   
  58.     PROCEDURE set;
  59.       BEGIN
  60.         WHILE bytes > 0 DO
  61.           to^:= from^;
  62.           to:= ADDRESS (to) + 1L;
  63.           from:= ADDRESS (from) + 1L;
  64.           DEC (bytes)
  65.         END
  66.       END set;
  67.   
  68.     PROCEDURE SuperPeek  ( addr: ADDRESS; VAR data: ARRAY OF BYTE );
  69.       BEGIN
  70.         from:= addr;
  71.         to:= ADR (data);
  72.         bytes:= HIGH (data)+1;
  73.         SuperExec ( ADDRESS (set) ) (* 'set' im Supervisor-Mode ausführen *)
  74.       END SuperPeek;
  75.   
  76.     PROCEDURE SuperLPeek ( addr: ADDRESS ): LONGCARD;
  77.       VAR data: LONGCARD;
  78.       BEGIN
  79.         from:= addr;
  80.         to:= ADR (data);
  81.         bytes:= 4;
  82.         SuperExec ( ADDRESS (set) ); (* 'set' im Supervisor-Mode ausführen *)
  83.         RETURN data
  84.       END SuperLPeek;
  85.   
  86.     PROCEDURE SuperLPoke ( addr: ADDRESS; data: LONGCARD );
  87.       BEGIN
  88.         from:= ADR (data);
  89.         to:= addr;
  90.         bytes:= 4;
  91.         SuperExec ( ADDRESS (set) ) (* 'set' im Supervisor-Mode ausführen *)
  92.       END SuperLPoke;
  93.   
  94.     END SysUtil1; (* lokales Modul *)
  95. *)
  96.  
  97. CONST Magic = 'XBRA';
  98.  
  99.       entryOffs = 12L; (* Differenz zw. 'Carrier.magic' und 'Carrier.entry' *)
  100.  
  101.  (*
  102.   * Hilfsfunktionen, die ggf. optimiert werden können
  103.   * -------------------------------------------------
  104.   *)
  105.  
  106. (*$Z+*)
  107. PROCEDURE equal (s1, s2: ID): BOOLEAN;
  108. (*$Z-,L-*)
  109.   BEGIN
  110.     ASSEMBLER
  111.         MOVE.L  -(A3),D0
  112.         CMP.L   -(A3),D0
  113.         SEQ     D0
  114.         ANDI    #1,D0
  115.         ; MOVE    D0,(A3)+
  116.     END
  117.   END equal;
  118.   (*$L=*)
  119.  
  120.  (*
  121.   * Exportierte Funktionen
  122.   * ----------------------
  123.   *)
  124.  
  125. PROCEDURE Create (VAR use: Carrier; nam: ID; call: ADDRESS;
  126.                   VAR entr: ADDRESS);
  127.   BEGIN
  128.     WITH use DO
  129.       name:= nam;
  130.       magic:= Magic;
  131.       prev:= NIL;
  132.       entry.jmpInstr:= JmpInstr; (* Code für 'JMP <adr>.L' *)
  133.       entry.operand:= call;
  134.       entr:= ADR (entry)
  135.     END
  136.   END Create;
  137.  
  138. PROCEDURE Installed (name: ID; vector: ADDRESS; VAR at: ADDRESS): BOOLEAN;
  139.   VAR lastentry, entry: ADDRESS; c: Carrier;
  140.   BEGIN
  141.     lastentry:= 0;
  142.     at:= vector; (* Vorwahl für RETURN FALSE *)
  143.     LOOP
  144.       entry:= SuperLPeek (vector);
  145.       IF (entry = 0) OR (entry = lastentry) THEN RETURN FALSE END;
  146.       SuperPeek (entry - entryOffs, c);
  147.       IF equal (c.magic, Magic) THEN
  148.         (* XBRA-Kennung gefunden *)
  149.         IF equal (c.name, name) THEN
  150.           (* Ende, da Name gefunden *)
  151.           at:= vector;
  152.           RETURN TRUE
  153.         ELSE
  154.           (* Vorgänger prüfen *)
  155.           vector:= entry - 4L;
  156.           lastentry:= entry
  157.         END
  158.       ELSE
  159.         (* Ende, da XBRA-Kette zuende *)
  160.         RETURN FALSE
  161.       END;
  162.     END;
  163.   END Installed;
  164.  
  165. PROCEDURE Install (entry: ADDRESS; at: ADDRESS);
  166.   VAR pc: POINTER TO Carrier;
  167.   BEGIN
  168.     IF (entry = NIL) OR (at = NIL) THEN
  169.       HALT
  170.     ELSE
  171.       pc:= entry - entryOffs;
  172.       pc^.prev:= SuperLPeek (at);
  173.       SuperLPoke (at, entry)
  174.     END
  175.   END Install;
  176.  
  177. PROCEDURE Remove (at: ADDRESS);
  178.   VAR entry: ADDRESS; c: Carrier;
  179.   BEGIN
  180.     IF at = NIL THEN
  181.       HALT
  182.     ELSE
  183.       entry:= SuperLPeek (at);
  184.       IF entry = NIL THEN
  185.         HALT
  186.       ELSE
  187.         SuperPeek (entry - entryOffs, c);
  188.         IF equal (c.magic, Magic) THEN
  189.           SuperLPoke (at, c.prev)
  190.         ELSE
  191.           HALT
  192.         END
  193.       END
  194.     END
  195.   END Remove;
  196.  
  197. PROCEDURE Query (vector: ADDRESS; with: QueryProc);
  198.   VAR lastentry, entry: ADDRESS; c: Carrier; dummy: BOOLEAN;
  199.   BEGIN
  200.     lastentry:= 0;
  201.     LOOP
  202.       entry:= SuperLPeek (vector);
  203.       IF (entry = 0) OR (entry = lastentry) THEN RETURN END;
  204.       SuperPeek (entry - entryOffs, c);
  205.       IF NOT equal (c.magic, Magic) THEN
  206.         EXIT
  207.       END;
  208.       IF NOT with (vector, c.name) THEN RETURN END;
  209.       (* Vorgänger ist dran *)
  210.       vector:= entry - 4L;
  211.       lastentry:= entry
  212.     END;
  213.     dummy:= with (vector, '????')
  214.   END Query;
  215.  
  216. PROCEDURE Entry (at: ADDRESS): ADDRESS;
  217.   BEGIN
  218.     RETURN SuperLPeek (at);
  219.   END Entry;
  220.  
  221. PROCEDURE Called (at: ADDRESS): ADDRESS;
  222.   VAR entry: ADDRESS; c: Carrier;
  223.   BEGIN
  224.     entry:= SuperLPeek (at);
  225.     IF entry # NIL THEN
  226.       SuperPeek (entry - entryOffs, c);
  227.       IF equal (c.magic, Magic) THEN
  228.         IF c.entry.jmpInstr = JmpInstr THEN
  229.           (* Wenn dies eine vom XBRA-Modul erzeugte Struktur ist, dann lie- *)
  230.           (* fern wir die Code-Adresse, die bei 'Install' angegeben wurde.  *)
  231.           RETURN c.entry.operand
  232.         END
  233.       END;
  234.       (* Ansonsten wird einfach die direkte Einsprungadr. geliefert *)
  235.       RETURN entry
  236.     END;
  237.     RETURN NIL
  238.   END Called;
  239.  
  240. PROCEDURE PreviousEntry (entry0: ADDRESS): ADDRESS;
  241.   VAR pc: POINTER TO Carrier;
  242.   BEGIN
  243.     IF entry0 # NIL THEN
  244.       pc:= entry0 - entryOffs;
  245.       WITH pc^ DO
  246.         IF equal (magic, Magic) AND (prev # entry0) THEN
  247.           RETURN prev
  248.         END
  249.       END
  250.     END;
  251.     RETURN NIL
  252.   END PreviousEntry;
  253.  
  254. END XBRA.
  255.